package com.societyGames.flashForms
{
	import com.societyGames.system.EventObject;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	public class ListContainer extends Sprite implements IChangeSize
	{
		private var _desiredHeight:Number;
		private var _desiredWidth:Number;
		private var _sizeChangedEventObject:EventObject;
		private var _items:Vector.<ListItem> = new Vector.<ListItem>();
		private var _selectedItem:ListItem;
		private var _overItem:ListItem;
		
		public function ListContainer()
		{
			this._sizeChangedEventObject = new EventObject(this, "SIZE_CHANGED");
		}

		public function addItem(item:ListItem):void
		{
			removeItem(item);
			_items.push(item);
			item.addEventListener(MouseEvent.CLICK, itemClickHandler);
			item.addEventListener(MouseEvent.ROLL_OVER, itemRollOverHandler);
			item.addEventListener(MouseEvent.ROLL_OUT, itemRollOutHandler);

			//Select the item first. This may cause resize, but that's OK, we've got a calculate later.
			if (this._selectedItem == null)
			{
				selectItem(item);
			}
			//Now hook up change size. Delayed so we don't calculate() on select item above.
			var changeSize:IChangeSize = item as IChangeSize;
			if (changeSize != null)
			{
				changeSize.sizeChangedEventObject.addEventListener(itemChangedSizeHandler);
			}
			calculate();
		}
		
		public function removeItem(item:ListItem):void
		{
			var index:int = this._items.indexOf(item);
			if (index != -1)
			{
				this._items.slice(index, 1);				
				item.removeEventListener(MouseEvent.CLICK, itemClickHandler);
				if (item == this._selectedItem) //Deselect and select another one.
				{
					if (this._items.length > 0)
					{
						selectItem(this._items[0]);
					}
					else
					{
						selectItem(null);
					}
				}
				var changeSize:IChangeSize = item as IChangeSize;
				if (changeSize != null)
				{
					changeSize.sizeChangedEventObject.removeEventListener(itemChangedSizeHandler);
				}
				calculate();
			}
		}
		
		public function clearItems():void
		{
			for each (var item:ListItem in this._items)
			{
				this.removeChild(item);
			}
			this._items.length = 0;
			calculate();
		}
		
		//Make all of the items in _items appear correctly.
		private function calculate():void
		{	
			//Wipe the children clean.
			while (this.numChildren > 0)
			{
				this.removeChildAt(this.numChildren - 1);
			}
			//Now re-add children back.
			var nextY:Number = 0;
			for each (var item:ListItem in this._items)
			{
				item.x = 0;
				item.y = nextY;	
				this.addChild(item);
				nextY += item.height;
			}
			calculateWidth();
			this._sizeChangedEventObject.dispatchEvent();
		}
		
		private function calculateWidth():void
		{
			for each (var item:ListItem in this._items)
			{
				item.width = this._desiredWidth;
			}
		}
		
		//IChangeSize-->
		public function get sizeChangedEventObject():EventObject
		{
			return this._sizeChangedEventObject;	
		}
		//<--IChangeSize

		//The height is ignored. List can keep growing in height as much as it wants.
		public override function set height(value:Number):void
		{	
			if (value != this._desiredHeight)
			{
				this._desiredHeight = value;			
			}
		}
		
		public override function set width(value:Number):void
		{
			if (value != this._desiredWidth)
			{
				this._desiredWidth = value;
				calculateWidth();
			}
		}
		
		public function selectItem(item:ListItem):void
		{	
			//Don't allow toggling. If we clicked the same object, just ignore it.
			if (this._selectedItem == item)
			{
				return;
			}
			if (this._selectedItem != null)
			{
				this._selectedItem.isSelected = false;
			}
			this._selectedItem = item;
			if (this._selectedItem != null)
			{
				this._selectedItem.isSelected = true;
			}
		}
		
		public function selectIndex(index:int):void
		{
			selectItem(this._items[index]);
		}
		
		public function get selectedItem():ListItem
		{
			return this._selectedItem;
		}
		
		private function setOverItem(listItem:ListItem):void
		{
			if (this._overItem != null)
			{
				this._overItem.isOver = false;
			}
			this._overItem = listItem;
			if (this._overItem != null)
			{
				this._overItem = listItem;
				this._overItem.isOver = true;
			}
		}
		
		private function itemChangedSizeHandler(event:Event):void
		{
			calculate();
		}
		
		private function itemClickHandler(event:MouseEvent):void
		{
			var item:ListItem = ListItem(event.currentTarget);
			selectItem(item);
		}
		
		private function itemRollOverHandler(event:MouseEvent):void
		{
			setOverItem(ListItem(event.target));
		}
		
		private function itemRollOutHandler(event:MouseEvent):void
		{
			setOverItem(null);
		}
	}
}